﻿// <copyright file="PermissionManager.cs" company="FounderSoftware">
// Copyright (c) 2008 All Right Reserved
// </copyright>
// <author>EvanStorm</author>
// <email>situ_yiwen@Founder.com</email>
// <date>2010-10-12</date>
// <summary>Logic class</summary>

using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using SZJT.Framework.Adapter;

namespace SZJT.Framework.Core
{
    public class PermissionManager
    {
        private static readonly object Lock = new object();
        private static IDictionary<string, PermissionEntity> _userPermList;
        private static Hashtable _certifiedPool;
        private static DateTime? _lastEditTime = null;
        /// <summary>
        /// 初始化权限池
        /// </summary>
        public static void BuildPermissionPool()
        {
            GetPermission(string.Empty);
        }
        /// <summary>
        /// 初始化认证池
        /// </summary>
        public static void BuildCertifiedPool()
        {
            //GetCertifiedPool(string.Empty);
        }
        /// <summary>
        /// 清除某个应用的权限池
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        public static void ClearPermissionPool(string taskGuid)
        {
            _userPermList.Remove(taskGuid);
        }
        /// <summary>
        /// 清除某个应用的认证池
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        public static void ClearCertifiedPool(string taskGuid)
        {
            _certifiedPool.Remove(taskGuid);
        }

        ///// <summary>
        ///// 根据应用标识检查认证
        ///// </summary>
        ///// <param name="taskGuid"></param>
        //public static void CheckedCertPool(string taskGuid)
        //{
        //    var pool = GetCertifiedPool(taskGuid).Pool;
        //    var temp = pool;
        //    foreach (var key in pool.Keys.Where(key => pool[key].RefreshTime < DateTime.Now))
        //    {
        //        temp.Remove(key);
        //    }
        //    GetCertifiedPool(taskGuid).Pool = temp;
        //}

        /// <summary>
        /// 根据应用标识获取权限对象
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <returns>权限对象</returns>
        public static PermissionEntity GetPermission(string taskGuid)
        {
            try
            {
                if (PermissionIsChanged())
                    _userPermList = null;
                if (null == _userPermList)
                {
                    lock (Lock)
                    {
                        if (null == _userPermList)
                        {
                            _userPermList = new Dictionary<string, PermissionEntity>();
                            var compConfig = new ComponentConfiguration();
                            var component = compConfig.GetComponent();
                            var taskList = AdapterFactory.TaskListStr.Trim(',').Split(',');
                            foreach (var appGuid in taskList)
                            {
                                var orgAdapter = AdapterFactory.GetAdapter(Constants.ORG_GUID);
                                var param = orgAdapter.GetData(Constants.ORG_GUID, appGuid, "RoleList");
                               
                                var permission = new PermissionEntity(param);
                                _userPermList.Add(appGuid, permission);
                            }
                        }
                    }
                }
                return _userPermList.ContainsKey(taskGuid) ? _userPermList[taskGuid] : null;
            }
            catch (Exception e)
            {
                LoggerHelper.WriteMessageInfo(e.Message);
                LoggerHelper.WriteStackTraceInfo(e.StackTrace);
                return null;
            }
        }
        ///// <summary>
        ///// 根据应用标识获取认证池
        ///// </summary>
        ///// <param name="taskGuid">应用标识</param>
        ///// <returns>认证池</returns>
        //public static CertifiedPoolEntity GetCertifiedPool(string taskGuid)
        //{
        //    try
        //    {
        //        //if (PermissionIsChanged())
        //        //    _certifiedPool = null;
        //        //if (null == _certifiedPool)
        //        //{
        //        //    lock (Lock)
        //        //    {
        //        //        if (null == _certifiedPool)
        //        //        {
        //        //            _certifiedPool = new Hashtable();
        //        //            var compConfig = new ComponentConfiguration();
        //        //            var components = compConfig.GetComponents();
        //        //            foreach (var component in components)
        //        //            {
        //        //                var guid = AdapterFactory.GetNameGuidTable()[component.AccountName].ToString();
        //        //                var certPool = new CertifiedPoolEntity();
        //        //                _certifiedPool.Add(guid, certPool);
        //        //            }
        //        //        }
        //        //    }
        //        //}
        //        return _certifiedPool.ContainsKey(taskGuid) ? _certifiedPool[taskGuid] as CertifiedPoolEntity : null;
        //    }
        //    catch (Exception e)
        //    {
        //        LoggerHelper.WriteMessageInfo(e.Message);
        //        LoggerHelper.WriteStackTraceInfo(e.StackTrace);
        //        return null;
        //    }
        //}
        /// <summary>
        /// 判断用户是否已被认证过
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="userId">用户标识</param>
        /// <param name="clientIP">客户端IP地址（CS模式才有）</param>
        /// <returns>认证结果</returns>
        //public static bool HasCertified(string taskGuid, string userId, string clientIP = "")
        //{
        //    var certPool = GetCertifiedPool(taskGuid);
        //    if (null == certPool) return false;
        //    CheckPoolUser(certPool, userId);
        //    return certPool.Pool.ContainsKey(userId) || Authentication(taskGuid, userId, clientIP);
        //}
        /// <summary>
        /// 对用户进行认证
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="userId">用户标识</param>
        /// <param name="clientIP">客户端IP地址（CS模式才有）</param>
        /// <returns>认证结果</returns>
        //public static bool Authentication(string taskGuid, string userId, string clientIP = "")
        //{
        //    var adapter = AdapterFactory.GetAdapter(Constants.ORG_GUID);
        //    if (null == adapter)
        //    {
        //        throw new Exception("未能获取组件：" + taskGuid + "适配器");
        //    }
        //    var ouInfo = adapter.GetData(Constants.ORG_GUID, userId, "Account");
        //    if (null == ouInfo)
        //    {
        //        ouInfo = adapter.GetData(Constants.ORG_GUID, userId, "Certificate");
        //        if (null == ouInfo)
        //            return false;
        //    }
        //    if (!ouInfo.SelectSingleNode("Document/Status").InnerXml.Equals("Enable")) return false;
        //    var ip = null == HttpContext.Current ? clientIP : HttpContext.Current.Request.UserHostAddress;
        //    if (ouInfo.SelectSingleNode("Document/Type").InnerXml.Equals("Application"))
        //    {
        //        var appInfo = adapter.GetData(Constants.ORG_GUID, userId, "Application");
        //        if (appInfo.SelectSingleNode("Document/IPAddress").InnerText.Equals(ip))
        //        {
        //            PushPool(taskGuid,
        //                     new ActiveUser(userId, ouInfo.SelectSingleNode("Document/AccountName").InnerXml,
        //                                    ouInfo.SelectSingleNode("Document/Name").InnerXml,
        //                                    ouInfo.SelectSingleNode("Document/Type").InnerXml, DateTime.Now,
        //                                    DateTime.Now, ip));
        //            return true;
        //        }
        //        return false;
        //    }
        //    PushPool(taskGuid, new ActiveUser(userId, ouInfo.SelectSingleNode("Document/AccountName").InnerXml,
        //                                    ouInfo.SelectSingleNode("Document/Name").InnerXml,
        //                                    ouInfo.SelectSingleNode("Document/Type").InnerXml, DateTime.Now,
        //                                    DateTime.Now, ip));
        //    return true;
        //}
        /// <summary>
        /// 将通过认证的用户信息加入对应应用的认证池
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="userInfo">用户信息</param>
        //private static void PushPool(string taskGuid, ActiveUser userInfo)
        //{
        //    var certPool = GetCertifiedPool(taskGuid);
        //    if (!certPool.Pool.ContainsKey(userInfo.Ticket))
        //        certPool.Pool.Add(userInfo.Ticket, userInfo);
        //}
        /// <summary>
        /// 检查认证池中的用户是否过期
        /// </summary>
        /// <param name="pool">认证池</param>
        /// <param name="userId">用户标识</param>
        //private static void CheckPoolUser(CertifiedPoolEntity pool, string userId)
        //{
        //    ActiveUser userInfo;
        //    pool.Pool.TryGetValue(userId, out userInfo);
        //    if (null == userInfo) return;
        //    var ts = (DateTime.Now - userInfo.RefreshTime).TotalSeconds;
        //    if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["CertPoolOutTime"]))
        //        return;
        //    var outTime = Convert.ToDouble(ConfigurationManager.AppSettings["CertPoolOutTime"]);
        //    if (ts > outTime)
        //    {
        //        pool.Pool.Remove(userId);
        //    }
        //}

        private static bool PermissionIsChanged()
        {
            var orgAdapter = AdapterFactory.GetAdapter(Constants.ORG_GUID);
            var timeNode = orgAdapter.GetData(Constants.ORG_GUID, string.Empty, Constants.ORG_LISTENER_INFO);
            //???????????????????wait for update
            if (null == timeNode)
                return true;
            var resultTime = Convert.ToDateTime(timeNode.SelectSingleNode("//PermissionEditTime"));
            if(_lastEditTime!=resultTime)
            {
                _lastEditTime = resultTime;
                return true;
            }
            return false;
        }
    }
}
